<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<style>
@keyframes a {}
@keyframes b {}
</style>
<div id="target"></div>
<script>
function setAnimationProperty(value) {
  target.style.animation = value;
  target.offsetTop;
}

function getAnimations() {
  return document.getAnimations();
}

function clearAnimations() {
  setAnimationProperty('none');
  assert_equals(getAnimations().length, 0);
}

test(() => {
  clearAnimations();
  setAnimationProperty('a 1000ms 1500ms forwards, a 2000ms 2500ms backwards, a 3000ms 3500ms both');
  var animations = getAnimations();
  assert_equals(animations.length, 3);
  assert_equals(animations[0].effect.getTiming()['duration'], 1000);
  assert_equals(animations[0].effect.getTiming()['delay'], 1500);
  assert_equals(animations[0].effect.getTiming()['fill'], 'forwards');

  assert_equals(animations[1].effect.getTiming()['duration'], 2000);
  assert_equals(animations[1].effect.getTiming()['delay'], 2500);
  assert_equals(animations[1].effect.getTiming()['fill'], 'backwards');

  assert_equals(animations[2].effect.getTiming()['duration'], 3000);
  assert_equals(animations[2].effect.getTiming()['delay'], 3500);
  assert_equals(animations[2].effect.getTiming()['fill'], 'both');
}, 'Multiple same animation names should start multiple animations.');

test(() => {
  clearAnimations();

  setAnimationProperty('a 1500ms paused, a 2500ms paused, a 3500ms paused');
  var animations = getAnimations();
  assert_equals(animations.length, 3);
  animations[0].currentTime = 1000;
  animations[1].currentTime = 2000;
  animations[2].currentTime = 3000;

  setAnimationProperty('a 1750ms paused, a 2750ms paused, a 3750ms paused');
  animations = getAnimations();
  assert_equals(animations.length, 3);

  assert_equals(animations[0].currentTime, 1000);
  assert_equals(animations[0].effect.getTiming()['duration'], 1750);

  assert_equals(animations[1].currentTime, 2000);
  assert_equals(animations[1].effect.getTiming()['duration'], 2750);

  assert_equals(animations[2].currentTime, 3000);
  assert_equals(animations[2].effect.getTiming()['duration'], 3750);
}, 'Multiple same animation names should persist with animation timing updates.');

test(() => {
  clearAnimations();

  setAnimationProperty('a 1500ms paused, a 2500ms paused, b 3500ms paused, b 4500ms paused');
  var animations = getAnimations();
  assert_equals(animations.length, 4);
  animations[0].currentTime = 1000;
  animations[1].currentTime = 2000;
  animations[2].currentTime = 3000;
  animations[3].currentTime = 4000;

  setAnimationProperty('a 1500ms paused, b 3500ms paused, a 2500ms paused, b 4500ms paused');
  animations = getAnimations();
  assert_equals(animations.length, 4);

  assert_equals(animations[0].currentTime, 1000);
  assert_equals(animations[0].effect.getTiming()['duration'], 1500);

  assert_equals(animations[1].currentTime, 3000);
  assert_equals(animations[1].effect.getTiming()['duration'], 3500);

  assert_equals(animations[2].currentTime, 2000);
  assert_equals(animations[2].effect.getTiming()['duration'], 2500);

  assert_equals(animations[3].currentTime, 4000);
  assert_equals(animations[3].effect.getTiming()['duration'], 4500);
}, 'Mixed multiple same animation names should persist based on their same name relative position');

test(() => {
  clearAnimations();

  setAnimationProperty('a 1500ms paused, a 2500ms paused, a 3500ms paused');
  var animations = getAnimations();
  assert_equals(animations.length, 3);
  animations[0].currentTime = 1000;
  animations[1].currentTime = 2000;
  animations[2].currentTime = 3000;

  setAnimationProperty('a 1500ms paused, b 2500ms paused, a 3500ms paused');
  animations = getAnimations();
  assert_equals(animations.length, 3);

  assert_equals(animations[0].currentTime, 1000);
  assert_equals(animations[0].effect.getTiming()['duration'], 1500);

  assert_equals(animations[1].currentTime, 0);
  assert_equals(animations[1].effect.getTiming()['duration'], 2500);

  assert_equals(animations[2].currentTime, 2000);
  assert_equals(animations[2].effect.getTiming()['duration'], 3500);
}, 'Removing same animation names should cancel animations from the end of the name list.');

test(() => {
  clearAnimations();

  setAnimationProperty('a 1500ms paused, a 2500ms paused');
  var animations = getAnimations();
  assert_equals(animations.length, 2);
  animations[0].currentTime = 1000;
  animations[1].currentTime = 2000;

  setAnimationProperty('a 3500ms paused, a 2500ms paused, a 1500ms paused');
  animations = getAnimations();
  assert_equals(animations.length, 3);

  assert_equals(animations[0].currentTime, 1000);
  assert_equals(animations[0].effect.getTiming()['duration'], 3500);

  assert_equals(animations[1].currentTime, 2000);
  assert_equals(animations[1].effect.getTiming()['duration'], 2500);

  assert_equals(animations[2].currentTime, 0);
  assert_equals(animations[2].effect.getTiming()['duration'], 1500);
}, 'Adding same animation names should start additional animations from the end of the name list.');
</script>
